package com.dd.cloud.user.service.paynotice.channel;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dd.cloud.common.constants.OrderConstants;
import com.dd.cloud.user.entity.order.OrderFlow;
import com.dd.cloud.user.enums.ExceptionEnum;
import com.dd.cloud.user.service.order.IOrderFlowService;
import com.dd.cloud.user.service.paynotice.NoticeOrderService;
import com.dd.cloud.user.service.paynotice.PayNoticeService;
import com.dd.cloud.common.enums.ZkExceptionEnum;
import com.dd.cloud.common.exception.ZekeException;
import com.zk.pay.channel.alipay.AlipayChannelNoticeService;
import com.zk.pay.model.MchInfoConfigContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

/**
 * <p>
 * 支付宝回调
 * </p>
 *
 * @author zeke
 * @since 2020-03-20
 */
@Service
@Slf4j
public class AlipayNoticeService implements PayNoticeService {
    @Autowired
    private AlipayChannelNoticeService alipayChannelNoticeService;
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;
    @Autowired
    private IOrderFlowService orderFlowService;
    @Autowired
    private NoticeOrderService noticeOrderService;

    /**
     * 支付宝支付回调
     * @param request
     */
    @Override
    public void payNotify(HttpServletRequest request, MutablePair<String, Object> mutablePair, MchInfoConfigContext mchInfoConfigContext) {
        JSONObject notifyRes = (JSONObject) mutablePair.getRight();
        handlerNotifyData(request,notifyRes);
    }

    /**
     * 支付宝退款回调
     * @param request
     */
    @Override
    public void refundNotify(HttpServletRequest request , Object params) {
        JSONObject notifyRes = (JSONObject) params;
        handlerNotifyData(request,notifyRes);
    }

    /**
     * 处理支付回调
     *
     * @param object 回调参数
     */
    public void handlerNotifyData(HttpServletRequest request, JSONObject object) {
        String outFlowTradeNo = object.getString("out_trade_no");
        //获取本项目的订单号
        //outFlowTradeNo = OrderConstants.getFlowNoIden(outFlowTradeNo);
        log.info("获取系统性单号:{}", outFlowTradeNo);
        //手动开启事务
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        OrderFlow flow;

        try {
            object.getDouble("total_amount");
            Integer totalFee = (int) (object.getDouble("total_amount")*100);
            QueryWrapper<OrderFlow> q = new QueryWrapper<>();
            q.lambda().eq(OrderFlow::getFlowNo, outFlowTradeNo);
            flow = orderFlowService.getOne(q);
            if (flow == null) {
                throw new ZekeException(ZkExceptionEnum.ORDER_NOT_FOUND);
            }
            if (!totalFee.equals(flow.getTotalFee())) {
                // 金额不符
                throw new ZekeException(ExceptionEnum.INVALID_ORDER_PARAM);
            }
            // 支付成功
            // 修改流水状态
            flow.setStatus(OrderConstants.FlowStatus.PAY);
            // 设置支付时间
            flow.setPayDate(LocalDateTime.now());
            // 设置支付方式
            //flow.set(OrderConstants.PayOrderCanal.ALICANAL);
            UpdateWrapper<OrderFlow> q2 = new UpdateWrapper<>();
            q2.lambda().eq(OrderFlow::getFlowNo, outFlowTradeNo);
            boolean count = orderFlowService.update(flow, q2);
            if (!count) {
                throw new ZekeException(ExceptionEnum.UPDATE_ORDER_STATUS_ERROR);
            }
            //手动提交事务
            dataSourceTransactionManager.commit(transactionStatus);//提交
        } catch (Exception e) {
            e.printStackTrace();
            //手动回滚事务
            dataSourceTransactionManager.rollback(transactionStatus);
            throw new ZekeException(ZkExceptionEnum.UPDATE_ERROR);
        }
        //汇总主订单
        noticeOrderService.calcMainOrder(request, flow.getOrderNo(), flow.getFlowNo(), OrderConstants.FlowType.PAY);
    }
}
